/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * DBServerEdit.java
 *
 * Created on May 5, 2012, 3:01:54 PM
 */
package db.server.GUI;

import db.server.BUS.DesignBUS;
import db.server.BUS.EditBUS;
import db.server.DTO.RowDTO;
import db.server.DTO.DesignTableDTO;

import java.awt.event.ActionEvent;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.DefaultTableModel;

import javax.xml.parsers.ParserConfigurationException;

/**
 *
 * @author QuangKhai
 */
public final class DBServerEdit extends javax.swing.JPanel {
    private DesignBUS designBUS = new DesignBUS();
    private EditBUS editBUS = new EditBUS();
    private DesignTableDTO tableDTO = new DesignTableDTO();    
    private DefaultTableModel tables = new DefaultTableModel();    
    
    private String designPath;
    private String editPath;
    
    private JTabbedPane tabpane;
    private JLabel lb_status;
    
    /** Creates new form DBServerEdit */
    public DBServerEdit(JTabbedPane tabpane, String editPath, String designPath, JLabel label) {
        initComponents();
        
        this.lb_status = label;
        this.editPath = editPath;
        this.designPath = designPath;
        this.tabpane = tabpane;
        this.tables = (DefaultTableModel) edittable.getModel();  
        
        setColumnTable();
        checkInput();
    }
    
    ///Support call save edit table from outside
    public void save(){
        ActionEvent evt = null;
        bt_saveActionPerformed(evt);
    }
    
    ///Auto insert row of column name
    public void setColumnTable(){
        tableDTO = designBUS.readDesignTable(designPath);
        tb_address.setText(editPath);
        tb_address.setToolTipText(editPath);
        tb_tablename.setText(tableDTO.getTableName());
        tb_tablename.setToolTipText(tableDTO.getTableName());
        
        List<RowDTO> lstRow = new ArrayList<RowDTO>();        
        lstRow = tableDTO.getLstRows();
        
        for(int i = 0; i < lstRow.size(); i++){  
            tables.addColumn(lstRow.get(i).getColumnName());
        }
        
        getEditTable();
        
        tables.insertRow(edittable.getRowCount(), new Object[]{});    
        
    }
    
    ///Get value of edit table to save 
    public void saveTable() throws ParserConfigurationException{
        int rowCount = edittable.getRowCount() - 1;
        int columnCount = tableDTO.getLstRows().size();
        List<String> lstValue = new ArrayList<String>();

        lstValue.add(editPath);
        for(int i = 0; i < rowCount; i++){
            for(int j = 0; j < columnCount; j++){
                lstValue.add(edittable.getValueAt(i, j).toString());
            }
        }
        
        editBUS.saveEditTable(lstValue, tableDTO, null);        
        lb_status.setText("Edit table is saved!");
    }
    
    ///Get value of edit table to EditTableDTO
    public void getEditTable(){
        List<List<String>> lstValue = new ArrayList<List<String>>();        
        lstValue = editBUS.readEditTable(editPath, tableDTO);
        
        int columns = tableDTO.getLstRows().size();
        int rows = lstValue.size();
        
        for(int i = 0; i < rows; i++){
            tables.insertRow(edittable.getRowCount(), new Object[]{});    
            for(int j = 0; j < columns; j++){                
                edittable.setValueAt(lstValue.get(i).get(j), i, j);                                
            }                
        }
    }
    
    ///Check input value
    public void checkInput(){
        CellEditorListener checkCellValue = new CellEditorListener() {

            @Override
            public void editingStopped(ChangeEvent e) {                
                int selectedColumn = edittable.getSelectedColumn();
                int selectedRow = edittable.getSelectedRow();
                int rowCount = edittable.getRowCount();
                
                String value = edittable.getValueAt(selectedRow, selectedColumn).toString();                
                RowDTO row = tableDTO.getLstRows().get(selectedColumn);
                
                if(selectedRow != rowCount && !row.isAllowNulls()){
                    if(value.isEmpty()){
                        JOptionPane.showMessageDialog(tabpane, "Dữ liệu không được bỏ trống", "Lỗi dữ liệu", 1);
                        return;
                    }
                }
                
                if(selectedRow != rowCount && row.getDataType().compareTo("varchar") == 0){
                    if(!checkDataType(value, 1)){
                        JOptionPane.showMessageDialog(tabpane, "Dữ liệu phải là kiểu varchar", "Lỗi dữ liệu", 1);
                        return;
                    }
                } else {
                    if(!checkDataType(value, 2)){
                        JOptionPane.showMessageDialog(tabpane, "Dữ liệu phải là kiểu số nguyên", "Lỗi dữ liệu", 1);
                        return;
                    }
                }
                
                if(selectedRow != rowCount && row.isPrimaryKey()){
                    if(!checkUnique(value, selectedColumn, selectedRow)){
                        JOptionPane.showMessageDialog(tabpane, "Dữ liệu đã bị trùng! Nhập lại.", "Lỗi dữ liệu", 1);
                        return;
                    }
                }
            }

            @Override
            public void editingCanceled(ChangeEvent e) {
                
            }
        };
        
        edittable.getDefaultEditor(String.class).addCellEditorListener(checkCellValue);
    }
    
    ///Check data type of value
    public boolean checkDataType(String value, int type){
        if(type == 1){ //String
            try {                  
                Integer.parseInt(value);  
                return false;  
            } catch(Exception e) {  
                return true;  
            } 
        } else { //Integer            
            try {                  
                Integer.parseInt(value);  
                return true;  
            } catch(Exception e) {  
                return false;  
            }  
        }
    }
    
    ///Check unique of value
    public boolean checkUnique(String value, int column, int row){
        int position = edittable.getRowCount() - row;
        int rowCount = 0;
        
        if(position == 0){
             rowCount = edittable.getRowCount();
        } else{// if(position == 1){
            rowCount = edittable.getRowCount() - 1;
        } 
        
        for(int i = 0; i < rowCount; i++){
            if(i != row){
                if(value.compareTo(edittable.getValueAt(i, column).toString()) == 0){
                    return false;
                }
            }
        }
        
        return true;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        JScrollPane1 = new javax.swing.JScrollPane();
        edittable = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        tb_address = new javax.swing.JTextField();
        bt_remove = new javax.swing.JButton();
        bt_save = new javax.swing.JButton();
        bt_cancel = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        tb_tablename = new javax.swing.JTextField();

        setPreferredSize(new java.awt.Dimension(580, 310));

        edittable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        edittable.setDoubleBuffered(true);
        edittable.setDragEnabled(true);
        edittable.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                edittableKeyTyped(evt);
            }
        });
        JScrollPane1.setViewportView(edittable);

        jLabel1.setFont(new java.awt.Font("Cambria", 0, 12));
        jLabel1.setText("Address");

        tb_address.setEditable(false);
        tb_address.setFont(new java.awt.Font("Cambria", 0, 12)); // NOI18N
        tb_address.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        bt_remove.setFont(new java.awt.Font("Cambria", 0, 12)); // NOI18N
        bt_remove.setText("Remove");
        bt_remove.setToolTipText("Remove");
        bt_remove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bt_removeActionPerformed(evt);
            }
        });

        bt_save.setFont(new java.awt.Font("Cambria", 0, 12)); // NOI18N
        bt_save.setText("Save");
        bt_save.setToolTipText("Save");
        bt_save.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bt_saveActionPerformed(evt);
            }
        });

        bt_cancel.setFont(new java.awt.Font("Cambria", 0, 12)); // NOI18N
        bt_cancel.setText("Cancel");
        bt_cancel.setToolTipText("Cancel");
        bt_cancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bt_cancelActionPerformed(evt);
            }
        });

        jLabel2.setFont(new java.awt.Font("Cambria", 0, 12));
        jLabel2.setText("Table name");

        tb_tablename.setEditable(false);
        tb_tablename.setFont(new java.awt.Font("Cambria", 0, 12)); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(tb_tablename, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(tb_address, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE))
                    .addComponent(JScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(bt_remove, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(bt_save, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(bt_cancel, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tb_address, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(tb_tablename, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(bt_remove)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(bt_save)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(bt_cancel))
                    .addComponent(JScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 261, Short.MAX_VALUE))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

private void bt_removeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bt_removeActionPerformed
// TODO add your handling code here:
    if(edittable.getSelectedRow() != edittable.getRowCount() - 1){
        tables.removeRow(edittable.getSelectedRow());    
        lb_status.setText("A row is removed");
    }else{
        lb_status.setText("You can't remove a empty row");
    }
}//GEN-LAST:event_bt_removeActionPerformed

private void bt_cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bt_cancelActionPerformed
// TODO add your handling code here:
    tabpane.remove(tabpane.getSelectedIndex());
}//GEN-LAST:event_bt_cancelActionPerformed

private void bt_saveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bt_saveActionPerformed
    if(edittable.getSelectedRow() > 0){
        if(edittable.getValueAt(edittable.getSelectedRow(), edittable.getSelectedColumn()) == null){
            JOptionPane.showMessageDialog(null, "Please press other places before save!");
            return;
        }    
    }
    
    try {
        // TODO add your handling code here:
        saveTable();
    } catch (ParserConfigurationException ex) {
        Logger.getLogger(DBServerEdit.class.getName()).log(Level.SEVERE, null, ex);
    }
}//GEN-LAST:event_bt_saveActionPerformed

private void edittableKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_edittableKeyTyped
// TODO add your handling code here:
    int index = edittable.getSelectedRow();
    
    if(index == edittable.getRowCount() - 1){
        tables.insertRow(edittable.getRowCount(), new Object[]{});
    }
}//GEN-LAST:event_edittableKeyTyped

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane JScrollPane1;
    private javax.swing.JButton bt_cancel;
    private javax.swing.JButton bt_remove;
    private javax.swing.JButton bt_save;
    private javax.swing.JTable edittable;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JTextField tb_address;
    private javax.swing.JTextField tb_tablename;
    // End of variables declaration//GEN-END:variables
}
